// ----------------------------------
// RSDK Project: Sonic 2
// Script Description: Swing Platform Object
// Script Author: Christian Whitehead/Simon Thomley
// Unpacked by Rubberduckycooly's script unpacker
// ----------------------------------

// ========================
// Aliases
// ========================

private alias object.propertyValue : object.length

private alias object.value0  : object.swingAngle
private alias object.value1  : object.drawPos.x
private alias object.value2  : object.drawPos.y
private alias object.value3  : object.collisionOffset.x
private alias object.value4  : object.collisionOffset.y
private alias object.value45 : object.canSnap

// States
private alias 0 : SWINGPLAT_SWING
private alias 1 : SWINGPLAT_SNAPPED
private alias 2 : SWINGPLAT_FLOATING

// Player Aliases
private alias object.xpos : player.xpos
private alias object.ypos : player.ypos

private alias object.value17 : debugMode.currentSelection


// ========================
// Function Declarations
// ========================

reserve function SwingPlatform_DebugDraw
reserve function SwingPlatform_DebugSpawn


// ========================
// Static Values
// ========================

private value SwingPlatform_startDebugID = 0


// ========================
// Function Definitions
// ========================

private function SwingPlatform_DebugDraw
	temp7 = debugMode[0].currentSelection
	temp7 -= SwingPlatform_startDebugID
	
	// Draw the post
	DrawSprite(0)
	
	// Draw the chains
	temp0 = 0
	temp1 = 16
	while temp0 < temp7
		Cos(temp2, 128)
		temp2 *= temp1
		temp2 <<= 7
		temp2 += object.xpos
		Sin(temp3, 128)

		temp3 *= temp1
		temp3 <<= 7
		temp3 += object.ypos

		DrawSpriteXY(1, temp2, temp3)
		temp0++
		temp1 += 16
	loop

	// Draw the platform itself
	temp1 -= 8
	Cos(temp2, 128)

	temp2 *= temp1
	temp2 <<= 7
	temp2 += object.xpos
	Sin(temp3, 128)

	temp3 *= temp1
	temp3 <<= 7
	temp3 += object.ypos

	DrawSpriteXY(2, temp2, temp3)
end function


private function SwingPlatform_DebugSpawn
	temp0 = debugMode[0].currentSelection
	temp0 -= SwingPlatform_startDebugID
	CreateTempObject(TypeName[Swing Platform], temp0, object.xpos, object.ypos)
	object[tempObjectPos].direction = object.direction
end function


// ========================
// Events
// ========================

event ObjectUpdate
	temp2 = object.xpos
	temp3 = object.ypos

	GetTableValue(object.angle, 12, StageSetup_oscillationTable)
	object.angle >>= 8
	if object.direction == FLIP_X
		object.angle ^= 0xFF
		object.angle += 0x81
	end if
	object.angle <<= 1

	temp1 = object.length
	temp1++
	temp1 <<= 4
	temp1 -= 8
	object.xpos = object.drawPos.x
	object.ypos = object.drawPos.y

	switch object.state
	case SWINGPLAT_SWING
		Cos(object.xpos, object.angle)
		object.xpos *= temp1
		object.xpos <<= 7
		object.xpos += temp2

		Sin(object.ypos, object.angle)
		object.ypos *= temp1
		object.ypos <<= 7
		object.ypos += temp3
		break

	case SWINGPLAT_SNAPPED
		object.ypos += object.yvel
		object.yvel += 0x3000
		temp7 = 1824 // Y level of oil in the level
		temp7 <<= 16
		if object.ypos >= temp7
			object.state++
		end if
		object.xpos += object.xvel
		break

	case SWINGPLAT_FLOATING
		Sin(object.ypos, object.swingAngle)
		object.swingAngle += 6
		object.swingAngle &= 0x1FF
		object.ypos >>= 7
		object.ypos += 1824
		object.ypos <<= 16
		break
		
	end switch

	object.collisionOffset.x = object.xpos
	object.collisionOffset.x &= 0xFFFF0000
	temp4 = object.drawPos.x
	temp4 &= 0xFFFF0000
	object.collisionOffset.x -= temp4

	object.collisionOffset.y = object.ypos
	object.collisionOffset.y &= 0xFFFF0000
	temp5 = object.drawPos.y
	temp5 &= 0xFFFF0000
	object.collisionOffset.y -= temp5

	object.drawPos.x = object.xpos
	object.drawPos.y = object.ypos

	object.xpos = temp4
	object.ypos = temp5
	foreach (GROUP_PLAYERS, currentPlayer, ACTIVE_ENTITIES)
		BoxCollisionTest(C_PLATFORM, object.entityPos, -32, -8, 32, 8, currentPlayer, C_BOX, C_BOX, C_BOX, C_BOX)
		if checkResult == true
			if object.state == SWINGPLAT_SWING
				if object.canSnap == true
					if object.angle == 0x000
						object.xvel = 0x20000
						object.priority = PRIORITY_ACTIVE
						object.state = SWINGPLAT_SNAPPED
					end if

					if object.angle == 0x100
						object.xvel = -0x20000
						object.priority = PRIORITY_ACTIVE
						object.state = SWINGPLAT_SNAPPED
					end if
				end if
			end if
			player[currentPlayer].xpos += object.collisionOffset.x
			player[currentPlayer].ypos += object.collisionOffset.y
		end if
	next

	if object.state > 0
		if object.outOfBounds == true
			object.xpos = temp2
			object.ypos = temp3
			if object.outOfBounds == true
				object.state = SWINGPLAT_SWING
				object.priority = PRIORITY_BOUNDS
				object.xvel = 0
				object.yvel = 0
			end if
		end if
	end if
	object.xpos = temp2
	object.ypos = temp3
end event


event ObjectDraw
	temp0 = 0
	temp1 = 16
	while temp0 < object.length
		Cos(temp2, object.angle)
		temp2 *= temp1
		temp2 <<= 7
		temp2 += object.xpos

		Sin(temp3, object.angle)
		temp3 *= temp1
		temp3 <<= 7
		temp3 += object.ypos

		DrawSpriteXY(1, temp2, temp3)
		temp0++
		temp1 += 16
	loop
	temp1 -= 8

	DrawSpriteXY(2, object.drawPos.x, object.drawPos.y)
	DrawSprite(0)
end event


event ObjectStartup
	LoadSpriteSheet("OOZ/Objects.gif")
	SpriteFrame(-8, -8, 16, 16, 51, 75)
	SpriteFrame(-8, -8, 16, 16, 51, 75)
	SpriteFrame(-32, -8, 64, 32, 68, 75)

	foreach (TypeName[Swing Platform], arrayPos0, ALL_ENTITIES)
		GetBit(object[arrayPos0].canSnap, object[arrayPos0].propertyValue, 7)
		object[arrayPos0].length &= 0x7F
	next

	temp0 = 0
	SwingPlatform_startDebugID = DebugMode_ObjCount
	SwingPlatform_startDebugID--
	while temp0 < 8
		SetTableValue(TypeName[Swing Platform], DebugMode_ObjCount, DebugMode_TypesTable)
		SetTableValue(SwingPlatform_DebugDraw, DebugMode_ObjCount, DebugMode_DrawTable)
		SetTableValue(SwingPlatform_DebugSpawn, DebugMode_ObjCount, DebugMode_SpawnTable)
		DebugMode_ObjCount++
		temp0++
	loop
end event


// ========================
// Editor Events
// ========================

event RSDKEdit
	if editor.returnVariable == true
		switch editor.variableID
		case EDIT_VAR_PROPVAL // property value
			checkResult = object.propertyValue
			break
			
		case 0 // length
			checkResult = object.propertyValue
			checkResult &= 0x7F
			break
			
		case 1 // canSnap
			GetBit(checkResult, object.propertyValue, 7)
			break
			
		end switch
	else
		switch editor.variableID
		case EDIT_VAR_PROPVAL // property value
			object.propertyValue = editor.variableValue
			break
			
		case 0 // length
			editor.variableValue &= 0x7F
			object.propertyValue &= 0x80

			object.propertyValue |= editor.variableValue
			break
			
		case 1 // canSnap
			CheckNotEqual(editor.variableValue, false)
			SetBit(object.propertyValue, 7, checkResult)
			break
			
		end switch
	end if
end event


event RSDKDraw
	temp7 = object.propertyValue
	temp7 &= 0x7F

	DrawSprite(0)

	temp0 = 0
	temp1 = 16
	while temp0 < temp7
		Cos(temp2, 128)
		temp2 *= temp1
		temp2 <<= 7
		temp2 += object.xpos

		Sin(temp3, 128)
		temp3 *= temp1
		temp3 <<= 7
		temp3 += object.ypos

		DrawSpriteXY(1, temp2, temp3)
		temp0++
		temp1 += 16
	loop
	temp1 -= 8

	Cos(temp2, 128)
	temp2 *= temp1
	temp2 <<= 7
	temp2 += object.xpos

	Sin(temp3, 128)
	temp3 *= temp1
	temp3 <<= 7
	temp3 += object.ypos

	DrawSpriteXY(2, temp2, temp3)
end event


event RSDKLoad
	LoadSpriteSheet("OOZ/Objects.gif")
	SpriteFrame(-8, -8, 16, 16, 51, 75)
	SpriteFrame(-8, -8, 16, 16, 51, 75)
	SpriteFrame(-32, -8, 64, 32, 68, 75)

	AddEditorVariable("length")
	SetActiveVariable("length")

	AddEditorVariable("canSnap")
	SetActiveVariable("canSnap")
	AddEnumVariable("false", false)
	AddEnumVariable("true", true)
end event
